/**
 * Created by 2006-1-29 23:20:55
 * $Id: Util.java 9 2006-03-08 10:21:59Z wjx $
 */
package com.someok.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Hashtable;

import org.apache.log4j.Logger;


/**
 * Utility class.
 *
 * <p>
 * <a href="Util.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author wjx
 * @version $Revision: 9 $ $Date: 2006-03-08 18:21:59 +0800 (星期三, 08 三月 2006) $
 */
public class Util {
	/** Log. */
	private static Logger log = Logger.getLogger(Util.class);

	/**
	 * Get the last token from the input string.
	 *
	 * @param str
	 *            the string containing the token
	 * @param tokenSeparator
	 *            the token separator string (i.e.: "'", ":", etc)
	 * @return the last token from the input string
	 */
	public static String getLastToken(String str, String tokenSeparator) {
		return str.substring(str.lastIndexOf(tokenSeparator) + 1, str.length());
	}



	/**
	 * Return the string representation of the input exception stack trace.
	 *
	 * @param t
	 *            the input throwable object
	 * @return the string representation of the stack trace of the input
	 *         throwable object
	 */
	public static String stackTrace(Throwable t) {
		StringWriter sw = new StringWriter();

		t.printStackTrace(new PrintWriter(sw));
		String s = sw.toString();

		try {
			sw.close();
		} catch (IOException e) {
			log.error("::stackTrace - cannot close the StringWriter object", e);
		}

		return s;
	}

	/**
	 * Reads from input and writes read data to the output, until the stream end.
	 *
	 * @param in
	 * @param out
	 * @param bufSizeHint
	 *
	 * @throws IOException
	 */
	public static void copyPipe(InputStream in, OutputStream out, int bufSizeHint) throws IOException {
		int read = -1;
		byte[] buf = new byte[bufSizeHint];
		while ((read = in.read(buf, 0, bufSizeHint)) >= 0) {
			out.write(buf, 0, read);
		}
		out.flush();
	}

	/**
	 * Dump the content of the input hash table.
	 *
	 * @param table
	 *            table the hash table to dump
	 * @param html
	 *            true to set the eof as "<br>
	 *            \n", false to set it as "\n"
	 * @return Description of the Return Value
	 */
	public static String dumpHashTable(Hashtable table, boolean html) {
		Enumeration keys = table.keys();
		Enumeration values = table.elements();
		StringBuffer sb = new StringBuffer();
		String eof = "\n";

		if (html)
			eof = "<br>\n";

		while (keys.hasMoreElements())
			sb.append("  key [").append(keys.nextElement().toString()).append(
					"] = [").append(values.nextElement().toString())
					.append("]").append(eof);

		return sb.toString();
	}

	/**
	 * Add a new parameter to the input URL string representation.
	 *
	 * @param URL
	 *            the URL string representation
	 * @param paramName
	 *            the parameter name
	 * @param paramValue
	 *            the parameter value
	 */
	public static String addURLParameter(String URL, String paramName,
			String paramValue) {
		String param = new StringBuffer(paramName).append("=").append(
				paramValue).toString();

		return addURLParameter(URL, param);
	}

	/**
	 * Add a new parameter to the input URL string representation.
	 *
	 * @param URL
	 *            the URL string representation
	 * @param parameter
	 *            the parameter string, encoded as "${paramName}=${paramValue}"
	 */
	public static String addURLParameter(String URL, String parameter) {
		StringBuffer sb = new StringBuffer(URL);

		if (URL.lastIndexOf('?') == -1)
			sb.append("?");
		else
			sb.append("&");

		sb.append(parameter);
		return sb.toString();
	}

	/**
	 * Remove the substring starting from the first character of the input
	 * string to the input <code>until</code> string included.
	 *
	 * @param str
	 *            the string to process
	 * @param until
	 *            the string to reach (it will removed, too)
	 * @return the substring starting from the first characther after the input
	 *         <code>until</code> string, or null if <code>until</code>
	 *         token isn't found
	 */
	public static String remove(String str, String until) {
		String val = null;
		int indx = str.indexOf(until);

		if (indx != -1)
			val = (str.substring((indx + until.length()), str.length()));

		return val;
	}

	/**
	 * Compare two objects just like "equals" would. Unlike Object.equals,
	 * this method allows any of the 2 objects to be null.
	 *
	 * @param obj1
	 * @param obj2
	 *
	 * @return true if equal, otherwise false
	 */
	public static boolean equals(Object obj1, Object obj2) {
		if (obj1 == null && obj2 == null) {
			return true;
		} else if (obj1 != null) {
			return obj1.equals(obj2);
		} else {
			return obj2.equals(obj1);
		}
	}

}
